package com.csw.android.ffmpegtest.ui.section2

import android.Manifest
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.csw.android.dev_utils.ex.FileEx.deepDelete
import com.csw.android.dev_utils.utils.SpaceLineDecoration
import com.csw.android.dev_utils.utils.ToastUtils
import com.csw.android.ffmpegtest.R
import com.csw.android.ffmpegtest.app.Config
import com.csw.android.ffmpegtest.databinding.LayoutSection201Binding
import com.csw.android.ffmpegtest.media.MediaFactory
import com.csw.android.ffmpegtest.media.play.base.IPlayer
import com.csw.android.ffmpegtest.media.play.base.IPlayerListener
import com.csw.android.ffmpegtest.media.record.base.IRecordListener
import com.csw.android.ffmpegtest.media.record.base.IRecorder
import com.csw.android.ffmpegtest.ui.base.DataBindingFragment
import com.tbruyelle.rxpermissions3.RxPermissions
import java.io.File

/**
 * 在 Android 平台使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放，并实现读写音频 wav 文件。
 * PCM是原始的音频数据，可以直接用AudioTrack进行播放。
 */
class Section201 : DataBindingFragment<LayoutSection201Binding>() {
    private var player: IPlayer? = null
    private var audioRecorder: IRecorder? = null
    private var adapter: WavFileAdapter? = null

    override fun getContentViewID(): Int {
        return R.layout.layout_section_201
    }

    override fun initView(rootView: View, savedInstanceState: Bundle?) {
        super.initView(rootView, savedInstanceState)
        dataBinding?.viewModel =
            ViewModelProvider(this).get(Section201ViewModel::class.java)
        dataBinding?.recyclerView?.run {
            addItemDecoration(SpaceLineDecoration.getInstanceByDp(0, 0, 0, 1, Color.BLACK))
            layoutManager = LinearLayoutManager(context)
        }
    }

    override fun initAdapter() {
        super.initAdapter()
        adapter = WavFileAdapter(this).apply {
            dataBinding?.recyclerView?.adapter = this
            setOnItemLongClickListener { _, view, position ->
                adapter?.getItem(position)?.deepDelete()
                dataBinding?.viewModel?.refreshFileList()
                return@setOnItemLongClickListener true
            }
            setOnItemClickListener { _, view, position ->
                adapter?.getItem(position)?.run {
                    player?.let { player ->
                        player.stop()
                        if (player.getFilePath() == this.path) {
                            return@setOnItemClickListener
                        }
                    }
                    player = MediaFactory.getPlayer(
                        "wav",
                        this@Section201,
                        path,
                        object : IPlayerListener {
                            override fun onStarted(player: IPlayer) {
                                dataBinding?.viewModel?.updatePlayState(
                                    player.getFilePath(),
                                    0
                                )
                            }

                            override fun onRunning(player: IPlayer, total: Long, curr: Long) {
                                dataBinding?.viewModel?.updatePlayState(
                                    player.getFilePath(),
                                    (curr * 100000 / total).toInt()
                                )
                            }

                            override fun onCompleted(player: IPlayer) {
                                dataBinding?.viewModel?.updatePlayState(
                                    player.getFilePath(),
                                    -1
                                )
                                if (this@Section201.player == player) {
                                    this@Section201.player = null
                                }
                            }

                            override fun onError(player: IPlayer, exception: Exception) {
                                exception.printStackTrace()
                                dataBinding?.viewModel?.updatePlayState(
                                    player.getFilePath(),
                                    -1
                                )
                                if (this@Section201.player == player) {
                                    this@Section201.player = null
                                }
                            }

                        })?.apply {
                        start()
                    }
                }
            }
        }
    }

    override fun initListener() {
        super.initListener()
        dataBinding?.record?.setOnClickListener {
            if (it.isSelected) {
                it.isSelected = false
                audioRecorder?.stop()
            } else {
                RxPermissions(this).request(Manifest.permission.RECORD_AUDIO)
                    .subscribe { b ->
                        if (b) {
                            it.isSelected = true
                            audioRecorder = MediaFactory.getRecorder(
                                "wav",
                                this@Section201,
                                Config.Section201.getWavPath(),
                                object : IRecordListener {
                                    override fun onStarted(recorder: IRecorder) {
                                        ToastUtils.showShort("开始录制")
                                    }

                                    override fun onRunning(
                                        recorder: IRecorder,
                                        startTime: Long,
                                        duration: Long,
                                        dataLength: Long
                                    ) {
                                        val second = duration / 1000
                                        val h = second / (60 * 60)
                                        val m = second / 60 % 60
                                        val s = second % (60 * 60)
                                        ToastUtils.showShort(
                                            String.format(
                                                "%02d:%02d:%02d %dk",
                                                h,
                                                m,
                                                s,
                                                dataLength / 1024
                                            )
                                        )
                                    }

                                    override fun onCompleted(recorder: IRecorder) {
                                        if (audioRecorder == recorder) {
                                            audioRecorder = null
                                            ToastUtils.showShort("录制完成")
                                            dataBinding?.viewModel?.refreshFileList()
                                        }
                                    }

                                    override fun onError(
                                        recorder: IRecorder,
                                        exception: Exception
                                    ) {
                                        File(recorder.getFilePath()).deepDelete()
                                        if (audioRecorder == recorder) {
                                            audioRecorder = null
                                            ToastUtils.showShort("录制失败")
                                        }
                                    }
                                }
                            )?.apply {
                                it.isSelected = true
                                start()
                            }
                        } else {
                            activity?.finish()
                        }
                    }
            }
        }
        dataBinding?.viewModel?.wavFileList?.observe(this) {
            adapter?.setNewInstance(it)
        }
    }

    override fun initData() {
        super.initData()
        dataBinding?.viewModel?.refreshFileList()
    }

    override fun onDestroyView() {
        adapter = null
        super.onDestroyView()
    }
}